/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-09     WangJing       the first version
 */
#include "RingBuffer.h"
#include <string.h>

void ringBuf_init(RingBuffer_t *rb, uint8_t *buffer, uint32_t size) {
    rb->head = 0;
    rb->tail = 0;
    rb->buf = buffer;
    rb->size = size;

    memset(rb->buf, 0, rb->size);
}

uint8_t ringBuf_isEmpty(RingBuffer_t *rb) {
    return rb->head == rb->tail;
}

uint8_t ringBuf_isFull(RingBuffer_t *rb) {
    return ((rb->head + 1) % rb->size) == rb->tail;
}

uint8_t ringBuf_write(RingBuffer_t *rb, uint8_t data) {
    if (ringBuf_isFull(rb)) {
        return 1;
    }

    rb->buf[rb->head] = data;
    rb->head = (rb->head + 1) % rb->size;

    return 0;
}

uint8_t ringBuf_read(RingBuffer_t *rb, uint8_t *data) {
    if (ringBuf_isEmpty(rb)) {
        return 1;
    }

    *data = rb->buf[rb->tail];
    rb->tail = (rb->tail + 1) % rb->size;

    return 0;
}

uint32_t ringBuf_getUsed(RingBuffer_t *rb) {
    if (rb->head >= rb->tail) {
        return rb->head - rb->tail;
    } else {
        return rb->size - rb->tail + rb->head;
    }
}

uint32_t ringBuf_getFree(RingBuffer_t *rb) {
    return rb->size - 1 - ringBuf_getUsed(rb);
}
